/**
 * tableExport（表格导出）
 */
layui.define(['cookie','yunj',"jquery","laytpl","validate"], function (exports) {
    let win = window;
    let doc = document;
    let $ = layui.jquery;
    let laytpl = layui.laytpl;
    let cookie = layui.cookie;
    let validate = layui.validate;

    class YunjTableExport{

        constructor(raw_table){
            this.version = '1.0.0';

            this.raw_table=raw_table;           // 要导出的表格对象
            this.raw_table_id=raw_table.id;     // 要导出的表格ID
            this.raw_table_items_total_count=raw_table.table_item_count;    // 要导出的表格数据总量

            this.request_url=null;              // 请求地址
            this.request_filter=null;           // 请求filter条件
            this.request_sort=null;             // 请求sort条件

            this.file = null;                   // 文件，包含name、ext

            this.is_can_request=true;           // 是否可以请求
            this.loadProgress=null;            // 加载进度对象

            this.has_checked_row = false;       // 存在数据行勾选

            this.cols = [];                     // 导出工作表表头
            this.sheet = [];                    // 导出工作表
            this.sheet_row_num = 0;             // 导出工作表行数

            this.prompt().then(res=>this.init());
        }

        // 提示
        prompt(){
            let that=this;

            return new Promise((resolve,reject) => {

                let key = yunj.currPageId()+":"+that.raw_table_id;

                let file = cookie.get(key);
                try{
                    file = JSON.parse(file);
                }catch (e){
                    file = {name:(doc.title?`${doc.title}_${that.raw_table_id}`:that.raw_table_id),ext:"xlsx"};
                }

                let content = `<div class="yunj-table-export-prompt-box">
                                <div class="label">文件名</div>
                                <div class="file-name">
                                    <input type="text" name="file_name" placeholder="汉字/字母/数字/_/-" value="${file.name}" autocomplete="off" class="layui-input">
                                </div>
                                <div class="file-ext">.xlsx</div>
                            </div>`;

                let options = {
                    type:1,
                    title:"确认导出？",
                    content:content,
                    btn:["确认","取消"],
                    shadeClose:true,
                    yes:function (idx,layero) {
                        let promptBoxEl = layero.find(".yunj-table-export-prompt-box");
                        let file = {
                            name:promptBoxEl.find("input[name=file_name]").val(),
                            ext:"xlsx"
                        };
                        validate.create({
                            rule:{
                                name:"require|chsDash",
                                ext:"require|in:xlsx"
                            },
                            message:{
                                "name.require":"文件名不能为空",
                                "name.chsDash":"文件名仅允许汉字/字母/数字/下划线_/破折号-组合",
                                "ext.require":"文件格式不能为空",
                                "ext.in":"文件格式选择错误",
                            }
                        });
                        validate.checkTips(file);
                        that.file = file;
                        yunj.isExistParent()?parent.layer.close(idx):layer.close(idx);
                        cookie.set(key,JSON.stringify(that.file));
                        resolve("done");
                    }
                };

                yunj.isExistParent()?parent.layer.open(options):layer.open(options);
            });

        }

        async init(){
            let that=this;
            await that.init_resource();
            that.set_data();
            that.exec();
        }

        async init_resource(){
            let that=this;
            await yunj.include_xlsx_style();
            return "done";
        }

        // 设置数据
        set_data(){
            let that=this;
            that.request_url=that.raw_table.url;
            that.set_request_filter();
            that.request_sort=that.raw_table.request_sort();
            that.is_can_request=true;
            that.set_cols();
            that.set_sheet_init();
        }

        set_request_filter(){
            let that=this;
            let requestFilter = that.raw_table.request_filter({
                ids:true,
                convert:false
            });
            that.has_checked_row = requestFilter.ids.length>0;
            that.request_filter = JSON.stringify(requestFilter);
        }

        set_cols(){
            let that=this;
            // 去掉操作栏（深拷贝，不影响原始值）
            let cols=JSON.parse(JSON.stringify(that.raw_table.table.config.cols))[0];
            for(let i=0;i<cols.length;i++){
                let col=cols[i];
                // 去掉隐藏的和操作栏
                if((col.hasOwnProperty("hide")&&col.hide)||(col.templet.length>0&&/^#templet_[\w]*_action$/.test(col.templet))){
                    cols.splice(i,1);
                    i--;
                    continue;
                }
                // id字段加上标题
                if(col.field === "id" && col.type === "checkbox") cols[i].title="ID";
                // 加上模板对象
                let tpl = col.templet.substr(0,1) === "#"?$(col.templet).html():col.templet;
                col.tplObj = tpl.length>0?laytpl(tpl):null;
                cols[i] = col;
            }
            that.cols = cols;
        }

        set_sheet_init(){
            let that=this;

            let sheet = [];
            let sheetColsWch = [];
            for(let i=0,l=that.cols.length;i<l;i++){
                let col = that.cols[i];
                let ref = XLSX.utils.encode_cell({c:i,r:0});
                sheet[ref] = {
                    v:col.title,
                    s:{
                        fill: {
                            fgColor: {
                                rgb: "FFC0C0C0"
                            }
                        },
                        font:{
                            name:"宋体",
                            sz:11
                        },
                        alignment:{
                            vertical:"center",
                            horizontal:"center",
                        },
                        border:{
                            right:{style:"thin"},
                            bottom:{style:"thin"},
                        }
                    }
                };
                // wch
                let wch = yunj.xlsx_sheet_cell_wch(col.title);
                wch = wch>10?wch:10;
                sheetColsWch.push({wch:wch});
            }
            sheet['!cols']=sheetColsWch;

            that.sheet = sheet;
            that.sheet_row_num = 1;
        }

        // 执行
        exec(){
            let that=this;
            yunj.loadProgress({
                tips:`表格数据，正在下载中...`,
                rand_progress:false,
                done:(obj)=>{
                    obj.set_tips(`表格数据，正在导出中...`);
                    that.save();
                },
                close:(obj)=>{
                    that.is_can_request=false;
                }
            }).then(obj=>{
                that.loadProgress=obj;
                // 数据请求
                that.request();
            });
        }

        /**
         * 数据请求
         * @param num   [请求批次]
         */
        request(num=1){
            let that=this;
            if(!that.is_can_request) return false;
            let requestData={builder_id:that.raw_table_id,builder_async_type:'export',num:num,filter:that.request_filter,sort:that.request_sort};
            yunj.request({
                url:that.request_url,
                data:requestData,
                eventTitle:'数据导出',
                loading: {enable: false},
                successCallback:function (requestArgs,responseRes) {
                    let data=responseRes.data;

                    // 拼接导出标识
                    data.items.map(item=>{
                        item.is_export=true;
                        return item;
                    });

                    if(data.items.length>0) that.items_push_sheet(data.items);

                    // 不存在数据行勾选
                    if(!that.has_checked_row){
                        // 判断是否继续请求数据(num*limit<item_count)
                        let isPage=data.page;           // 是否分页
                        let currNum=data.num | 0;       // 当前数据请求批次
                        let currLimit=data.limit | 0;   // 每批次请求数据量
                        let itemsCount = currNum*currLimit;
                        if(isPage&&itemsCount<that.raw_table_items_total_count){
                            let progress=((itemsCount*100)/that.raw_table_items_total_count)|0;
                            progress=progress>99?99:progress;
                            that.loadProgress.reset_progress(progress);
                            that.request(currNum+1);
                            return false;
                        }
                    }
                    that.loadProgress.reset_progress(100);
                },
                errorCallback:function (requestArgs, responseRes) {
                    yunj.close(that.loadProgress.index);
                    let errmsg = !responseRes ? `${requestArgs.eventTitle}失败` : responseRes.msg;
                    yunj.alert(errmsg, yunj.icon.error);
                }
            });
        }

        item_cell_val(item,col){
            let that = this;
            if(!col.tplObj) return item[col.field];
            try{
                let html = col.tplObj.render(item);
                return yunj.trim($(html).text());
            }catch (e){
                console.log(e.message,item);
                return item[col.field];
            }
        }

        items_push_sheet(items){
            let that = this;

            items.forEach(item=>{
                let r = that.sheet_row_num;
                for(let i=0,l=that.cols.length;i<l;i++){
                    let col = that.cols[i];
                    let ref = XLSX.utils.encode_cell({c:i,r:r});
                    that.sheet[ref] = {
                        v:that.item_cell_val(item,col),
                        s:{
                            font:{
                                name:"宋体",
                                sz:11
                            },
                            alignment:{
                                vertical:"center"
                            }
                        }
                    };
                }
                that.sheet_row_num++;
            });
        }

        save(){
            let that=this;

            that.sheet["!ref"] = XLSX.utils.encode_range({s: {c:0, r:0}, e: {c:that.cols.length-1, r:that.sheet_row_num }});

            let workbook = {
                SheetNames: ["sheet"],
                Sheets: {sheet:that.sheet},
            };

            // excel的配置项
            let wopts = {
                bookType: that.file.ext,     // 要生成的文件类型
                bookSST: false,             // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
                type: 'binary'
            };
            let wbout = XlsxStyle.write(workbook, wopts);
            // blob
            let blob = new Blob([yunj.str_to_array_buffer(wbout)], {type:"application/octet-stream"});

            yunj.download({name:`${that.file.name}.${that.file.ext}`,blob:blob});
        }

    }

    let tableExport = (raw_table)=>{
        if(yunj.isMobile()) return yunj.alert('抱歉！暂不支持移动端导出数据','warn');
        new YunjTableExport(raw_table);
    };

    exports('tableExport', tableExport);
});